<template>
  <div class="container-publish">
    <el-card>
      <div slot="header">
        <my-bread>{{$route.query.id?'修改文章':'发布文章'}}</my-bread>
      </div>
      <!-- 表单 -->
      <!-- 校验规则  :model=""  :rules="" -->
      <el-form ref="articleForm" :model="articleForm" :rules="articleRules" label-width="120px">
        <!-- prop="" 用来指定用 title 规则校验 -->
        <el-form-item label="标题" prop="title">
          <el-input v-model="articleForm.title" placeholder="请输入文章标题" style="width:400px"></el-input>
        </el-form-item>
        <el-form-item label="内容" prop="content">
          <!-- trigger:blur 无法监听富文本失去焦点去进行校验 -->
          <quill-editor
            @blur="checkContent()"
            v-model="articleForm.content"
            :options="editorOption"
          />
        </el-form-item>
        <el-form-item label="封面: " prop="cover.type">
          <el-radio-group @change="articleForm.cover.images=[]" v-model="articleForm.cover.type">
            <el-radio :label="1">单图</el-radio>
            <el-radio :label="3">三图</el-radio>
            <el-radio :label="0">无图</el-radio>
            <el-radio :label="-1">自动</el-radio>
          </el-radio-group>
          <!-- 一张图 -->
          <div style="margin-top:10px" v-if="articleForm.cover.type===1">
            <my-image @on-confirm="checkCover()" v-model="articleForm.cover.images[0]"></my-image>
          </div>
          <!-- 三张图 -->
          <div style="margin-top:10px" v-if="articleForm.cover.type===3">
            <my-image
              @on-confirm="checkCover()"
              v-for="i in 3"
              :key="i"
              v-model="articleForm.cover.images[i-1]"
            ></my-image>
          </div>
        </el-form-item>
        <el-form-item label="频道: " prop="channel_id">
          <my-channel v-model="articleForm.channel_id"></my-channel>
        </el-form-item>
        <!-- 填充表单（发请求获取文章数据，赋值表单） -->
        <el-form-item v-if="$route.query.id">
          <el-button @click="editArticle()" type="success">修改文章</el-button>
        </el-form-item>
        <el-form-item v-else>
          <el-button @click="saveArticle(false)" type="primary">发布文章</el-button>
          <el-button @click="saveArticle(true)">存入草稿</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<script>
// 富文本的样式
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
// 导入组件
import { quillEditor } from "vue-quill-editor";

export default {
  name: "page-publish",
  // 注册组件
  components: {
    quillEditor
  },
  data() {
    // 校验 封面数据cover
    const validCoverFn = (rule, value, callback) => {
      // value (数值)封面类型：1 3 0 -1 这些类型，就是cover.type
      const images = this.articleForm.cover.images;
      if (value === 1) {
        // 单图校验逻辑
        if (images[0] && images.length === 1) {
          callback();
        } else {
          callback(new Error("请选择一张封面图"));
        }
      } else if (value === 3) {
        // 三图校验逻辑
        if (images[0] && images[1] && images[2]) {
          callback();
        } else {
          callback(new Error("请选择三张封面图"));
        }
      } else {
        // 其他情况 校验成功
        callback();
      }
    };
    return {
      // 文章表单数据对象
      articleForm: {
        title: null,
        channel_id: null,
        content: null,
        cover: {
          type: 1,
          images: []
        }
      },
      // 文章校验规则对象
      articleRules: {
        title: [
          { required: true, message: "请输入文章标题", trigger: "blur" },
          { min: 5, max: 30, message: "标题5~30个字符", trigger: "blur" }
        ],
        content: [
          { required: true, message: "请输入文章内容", trigger: "blur" }
        ],
        channel_id: [
          { required: true, message: "请选择文章频道", trigger: "change" }
        ],
        // 单选项框组绑定的是 articleForm.cover.type 它能触发change来进行校验
        "cover.type": [{ validator: validCoverFn, trigger: "change" }]
      },
      // 富文本的配置对象（不需要提交给后台）
      editorOption: {
        placeholder: "请输入文章内容",
        modules: {
          toolbar: [
            ["bold", "italic", "underline", "strike"],
            ["blockquote", "code-block"],
            [{ header: 1 }, { header: 2 }],
            [{ list: "ordered" }, { list: "bullet" }],
            [{ indent: "-1" }, { indent: "+1" }],
            ["image"]
          ]
        }
      }
    };
  },
  created() {
    // 区分业务场景
    // 如果组件初始化，默认发布文章场景
    if (this.$route.query.id) {
      this.getAriticle();
    }
  },
  // 侦听器
  watch: {
    // 监听地址栏ID数据的变化，区分两种业务场景
    "$route.query.id": function() {
      if (this.$route.query.id) {
        // 修改文章 + 填充表单
        this.getAriticle();
      } else {
        // 发布文章 + 重置表单 （还原数据，清除校验）
        this.$refs.articleForm.resetFields();
        // 手动清除 赋值数据类型
        this.articleForm.cover.images = [];
      }
    }
  },
  methods: {
    // 修改文章
    editArticle() {
      // 整体表单校验
      this.$refs.articleForm.validate(async valid => {
        // 判断校验结果
        if (valid) {
          try {
            // 进行修改请求
            await this.$http.put(
              `articles/${this.$route.query.id}?draft=false`,
              this.articleForm
            );
            this.$message.success("修改文章成功");
            this.$router.push("/article");
          } catch (e) {
            tthis.$message.error("修改文章失败");
          }
        }
      });
    },
    // 获取文章 + 填充表单
    async getAriticle() {
      const res = await this.$http.get(`articles/${this.$route.query.id}`);
      this.articleForm = res.data.data;
    },
    // 添加文章 (形参draft 表示是否存为草稿)
    saveArticle(draft) {
      // 整体表单校验
      this.$refs.articleForm.validate(async valid => {
        // 是否校验成功的判断
        if (valid) {
          try {
            // 进行添加请求
            await this.$http.post(`articles?draft=${draft}`, this.articleForm);
            // 成功提示
            this.$message.success(draft ? "存入草稿成功" : "发布文章成功");
            // 跳转内容管理
            this.$router.push("/article");
          } catch (e) {
            // 失败提示
            this.$message.error(draft ? "存入草稿失败" : "发布文章失败");
          }
        }
      });
    },
    // 触发文章内容校验
    checkContent() {
      // 通过表单组件来使用声明好的content校验规则去校验content字段
      // 表单组件提供一个函数：validateField('字段名字') 进行校验
      this.$refs.articleForm.validateField("content");
    },
    // 触发文章封面的校验
    checkCover() {
      // 触发 cover.type校验规则，去校验封面图数据
      this.$refs.articleForm.validateField("cover.type");
    }
  }
};
</script>

<style scoped lang="less">
// ::v-deep 是深度作用符号，让选择器在其他组件下也生效。
.container-publish ::v-deep .ql-editor {
  height: 260px;
}
::v-deep .ql-toolbar.ql-snow {
  padding: 0 8px;
}
</style>